package com.psp.util;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.psp.util.StockUtils.getStockClosePriceByBaidu;

public class StockIndexUtils {

    /**
     * 计算MACD指标
     *
     * @param closePrices 收盘价
     * @return MACD指标
     */
    public static Map<String, double[]> calculateMACD(double[] closePrices) {

        double[] difArray = new double[closePrices.length];
        double[] deaArray = new double[closePrices.length];
        double[] macdArray = new double[closePrices.length];

        double[] ema12 = getEMA(closePrices, 12);
        double[] ema26 = getEMA(closePrices, 26);

        for (int i = 0; i < closePrices.length; i++) {
            difArray[i] = NumberUtil.round(ema12[i] - ema26[i], 4).doubleValue();
        }
        deaArray[0] = difArray[0];
        for (int i = 1; i < closePrices.length; i++) {
            deaArray[i] = NumberUtil.round(deaArray[i - 1] * 8 / 10 + difArray[i] * 2 / 10, 4).doubleValue();
        }
        for (int i = 0; i < closePrices.length; i++) {
            macdArray[i] = NumberUtil.round(2 * (difArray[i] - deaArray[i]), 4).doubleValue();
        }

        Map<String, double[]> result = new HashMap<>();
        result.put("dif", difArray);
        result.put("dea", deaArray);
        result.put("macd", macdArray);
        return result;
    }

    public static double[] getEMA(double[] prices, int n) {
        double[] emaArray = new double[prices.length];
        emaArray[0] = prices[0];
        for (int i = 1; i < prices.length; i++) {
            emaArray[i] = (2 * prices[i] + (n - 1) * emaArray[i - 1]) / (n + 1);
        }
        return emaArray;
    }

    /**
     * 计算MACD指标
     *
     * @param data [[开盘,收盘,最高,最低],[]]
     * @return MACD指标
     */
    public static Map<String, double[]> calculateKDJ(double[][] data) {

        double[] kVal = new double[data.length];
        double[] dVal = new double[data.length];
        double[] jVal = new double[data.length];
        for (int i = 0; i < data.length; i++) {
            if (i < 8) {
                kVal[i] = 50;
                dVal[i] = 50;
                jVal[i] = 50;
                continue;
            }

            double c = data[i][1]; // 当日收盘价
            double l9 = Arrays.stream(Arrays.copyOfRange(data, i - 8, i + 1))
                    .flatMapToDouble(Arrays::stream)
                    .min().orElse(0);
            double h9 = Arrays.stream(Arrays.copyOfRange(data, i - 8, i + 1))
                    .flatMapToDouble(Arrays::stream)
                    .max().orElse(0);

            double rsv = (c - l9) / (h9 - l9) * 100;   // 当日RSV值
            double k = NumberUtil.round(kVal[i - 1] * 2 / 3 + rsv / 3, 2).doubleValue();
            double d = NumberUtil.round(dVal[i - 1] * 2 / 3 + k / 3, 2).doubleValue();
            double j = NumberUtil.round(3 * k - 2 * d, 2).doubleValue();

            kVal[i] = k;
            dVal[i] = d;
            jVal[i] = j;
        }
        Map<String, double[]> result = new HashMap<>();
        result.put("kVal", kVal);
        result.put("dVal", dVal);
        result.put("jVal", jVal);
        return result;

    }

    public static void main(String[] args) {
        List<List<String>> r = getStockClosePriceByBaidu("600036");
        System.out.println(JSON.toJSONString(r));
        assert r != null;
        double[] macdData = r.stream().map(sub -> Double.parseDouble(sub.get(2))).mapToDouble(Double::doubleValue).toArray();
        System.out.println(JSON.toJSONString(calculateMACD(macdData)));

        String p = HttpUtil.get("http://124.221.69.33:8080/eye/stockPrice/getHistoryPriceByStockCode?stockCode=600036");
        JSONObject map = JSON.parseObject(p);
        String pJson = ((JSONObject) map.get("data")).get("price").toString();
        List<List<String>> resultList = JSON.parseObject(pJson, new TypeReference<List<List<String>>>() {
        });
        System.out.println(resultList);

        double[][] kdjData = resultList.stream()
                .map(row -> new double[]{Double.parseDouble(row.get(0)), Double.parseDouble(row.get(1)), Double.parseDouble(row.get(2)), Double.parseDouble(row.get(3))})
                .toArray(double[][]::new);
        System.out.println(JSON.toJSONString(kdjData));
        System.out.println(JSON.toJSONString(calculateKDJ(kdjData)));


    }
}
